<?php

namespace app\service;

use think\Cache;
use think\Exception;

class LockService
{
    // 获取锁（带唯一标识）
    public static function acquire($key, $expire = 10)
    {
        $redis = Cache::store('redis')->handler();
        $lockKey = "lock:{$key}";
        $identifier = uniqid();
        if ($redis->set($lockKey, $identifier, ['nx', 'ex' => $expire])) {
            return $identifier;
        }
        return false;
    }

    // 释放锁
    public static function release($key, $identifier)
    {
        $redis = Cache::store('redis')->handler();
        $lockKey = "lock:{$key}";
        $script = <<<LUA
            if redis.call("get", KEYS[1]) == ARGV[1] then
                return redis.call("del", KEYS[1])
            else
                return 0
            end
        LUA;
        return $redis->eval($script, [$lockKey, $identifier], 1);
    }

    // 安全执行（自动获取释放锁）
    public static function safeExecute($key, callable $callback, $expire = 10)
    {
        $stockId = self::acquire($key,$expire);

        if(!$stockId){
            throw new \Exception('系统繁忙，请稍后再试');
        }
        try{
            return call_user_func($callback);
        }finally{
            self::release($key,$stockId);
        }
    }
}